package com.dili.dd.gpi.service;

import com.dili.dd.gpi.domain.UidNameSpace;
import com.dili.dd.gpi.enums.ApplyType;
import com.dili.dd.gpi.enums.PrefixType;
import com.dili.dd.gpi.exception.BusinessException;
import com.dili.dd.gpi.util.spring.DataSourceLookupKey;
import com.dili.dd.gpi.util.spring.RequireDataSource;

/**
 * 命名空间（前缀）管理
 * Created by zhaoYuan on 2015/3/24.
 */
public interface UidNameSpaceService {

    /**
     * 无前缀
     */
    String UN_PREFIX = "";
    String API_DEFAULT_PREFIX = "Z";
    int UN_PREFIX_DEFAULT_VALUE = 0;
    int PREFIX_DEFAULT_VALUE = 99;
    int PREFIX_MAX_VALUE = 999;

    @RequireDataSource(key = DataSourceLookupKey.GPI_DATASOURCE)
    UidNameSpace get(Integer id);

    @RequireDataSource(key = DataSourceLookupKey.GPI_DATASOURCE)
    UidNameSpace getByPrefix(PrefixType prefixType, String prefix, String level);


//    void add(@NotNull PrefixType prefixType,String prefix,int currentValue);

    /**
     * 生成唯一id
     * =======================================
     * 生成规则：
     * 有前缀的：prefix + 固定3位自增id（100-999）
     * 无前缀的：小于等于3位，1-999
     * 保留空间：保留空间前缀 + 无前缀 （共2-4位）
     * 自动生成系统：CMS,七巧板等通过接口调用生成的唯一id，统一以 小写字母z 开头。长度不限。
     * =======================================
     * 保留空间：[a-zA-Z],无前缀id空间使用满时，会使用保留空间前缀
     * 保留空间：小写 z。CMS,七巧板等通过接口调用生成的唯一id，统一以 小写字母z 开头。长度不限。
     * 保留空间：大写的Z，作为在保留空间已经写满后。作为前缀来标识，无自定义前缀的id；不限长
     * 前缀规则：可以是不与保留空间冲突的任意字符串。即：1.不能为单个的字母[a-zA-Z]；2.不能为以[zZ]开头的串
     * @param prefixType
     * @param prefix
     * @param applyType
     * 1.如果 prefix不为空，则查找是否已经存在，存在则从原来的继续生成，否则，新建namespace。
     * 2.如果为空，则不使用命名空间。如果值已满（大于三位）。则使用保留命名空间[a-z][A-Z]。每个保留空间也只能容纳3位。
     * @param level
     * @return
     */
    @RequireDataSource(key = DataSourceLookupKey.GPI_DATASOURCE)
    String generateUID(PrefixType prefixType, String prefix, ApplyType applyType, String level) throws BusinessException;
}
